package com.ezbuy.common.helper;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

import java.io.*;

/**
 * ezbuy 2018/12/1 下午5:32
 */
public class FreeMakerHelper {


    /**
     * Bean -> Java
     *
     * @param data         数据模型,必须有get方法,否则获取不到属性,FreeMaker报错
     * @param packageName 输出文件夹(例如:address)
     * @param fileName    输出文件名字(例如:PhoneType)
     * @param fileType    输出文件类型(例如:.java)
     * @param ftlName     模板文件名字(例如Enum)
     * @param ftlDir      模板文件目录(例如:src/main/java/resources/ftl)
     * @param outDir      输出根目录(例如:src/main/java/resources/gen)
     */
    public static void generate(Object data, String packageName, String fileName, String fileType, String ftlName, String ftlDir, String outDir) {
        // step1 创建freeMarker配置实例
        Configuration configuration = new Configuration();
        Writer out = null;
        String filePath = fileName;
        try {
            // step2 获取模版路径
            configuration.setDirectoryForTemplateLoading(new File(ftlDir));
            configuration.setDefaultEncoding("UTF-8");
            configuration.setObjectWrapper(new DefaultObjectWrapper());
            // step4 加载模版文件
            Template template = configuration.getTemplate(ftlName + ".ftl");
            // step5 生成数据
            //创建文件夹
            String dirPath = Config.projectPath + File.separator + outDir + File.separator + packageName;
            if (!FileUtils.isFileExists(dirPath)) {
                System.out.println("文件夹不存在,先创建文件夹:" + dirPath);
                FileUtils.createOrExistsDir(dirPath);
            }
            //创建文件
            filePath = outDir + File.separator + packageName + File.separator + fileName + fileType;
            File docFile = new File(filePath);
            if (FileUtils.isFileExists(docFile)) {
                System.out.println("文件已经存在,先删除:" + fileName);
                FileUtils.delete(docFile);
            }
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
            // step6 输出文件
            template.process(data, out);
            System.out.println("生成成功:" + filePath);
        } catch (Exception e) {
            //生成失败就自动删除掉创建的文件,免得遗留的错误文件导致下次编译不通过
            FileUtils.delete(Config.projectPath + File.separator +filePath);
            throw new RuntimeException("生成失败：" + filePath, e);
        } finally {
            try {
                if (null != out) {
                    out.flush();
                }
            } catch (Exception e2) {
                throw new RuntimeException("生成异常：" + filePath, e2);
            }
        }
    }

}
